import { useEffect, useState, useRef } from "react"
import { Button, Input, message, Spin } from "antd";
import styles from './roadmap.module.scss';
import Actions from '../../action/index'
import { connect } from "react-redux";
import { loadStdlib } from '@reach-sh/stdlib';
import * as RoleType from '../../rshUtil/test.main.mjs'

const { Search, TextArea } = Input;
const stdlib = loadStdlib(process.env);
//代币的缩写
const { standardUnit } = stdlib

const waitSleepHandle = (time) => new Promise(resolve => {
    console.log(`这是定时处理什么东西吗`)
    return setTimeout(resolve, time)
});
//手势的编号id
const handToInt = { 'ROCK': 0, 'PAPER': 1, 'SCISSORS': 2 };
//结果
const intToOutcome = ['Bob wins!', 'Draw!', 'Alice wins!'];
// console.log(stdlib)
function Roadmap(props) {

    const [role, setRole] = useState('')

    const setRoleHandle = async (value) => {
        if (Object.keys(props.account).length == 0) {
            const account = await stdlib.getDefaultAccount()
            props.getWalletInfo(account)
        }
        setRole(value)
    }

    return (<div className={styles.roadmap}>
        {role ? <RoleView role={role} /> : <SelectRole handle={setRoleHandle}></SelectRole>}
    </div>)
}


function SelectRole({ handle }) {
    return <div className={styles.selectRole}>
        <Button className={styles.buttonView} type={'primary'} onClick={() => handle('Airdropper')}>{'开始游戏'}</Button>
        <Button className={styles.buttonView} type={'primary'} onClick={() => handle('Recipient')}>{'参与游戏'}</Button>
    </div>
}

export default connect(state => ({ ...state.home }), { ...Actions })(Roadmap);


function RoleView({ role }) {

    return <div className={styles.roleView}>
        {role == 'Airdropper' ? <AirdropperView /> : <RecipientView />}
    </div>
}

function Recipient({ account }) {
    //支付状态
    const resolveFuc1 = useRef(null)
    //等待结果状态
    const resolveFuc2 = useRef(null)

    const [recipient, setRecipient] = useState({
        //链接合约的字符串
        connectAddress: '',
        //展示输入合约的前端结构开关
        inputSwitch: false,
        //支付前端结构开关
        paySwitch: false,
        //支付的金额
        payWager: 0,
        //打开手势的前端结构开关
        playSwitch: false,
        //等待状态开关的前端结构
        waitAction: false,
        //
        lastResult: null,
        //购买的代币前端结构开关
        buySwitch: true,
        //
        number: 0

    })


    //购买处理（暂时简化增加代币）
    const onBuyTokenHandle = async (value) => {
        if (!value) {
            return
        }
        //获取当前区块链网络
        const faucet = await stdlib.getFaucet()
        // console.log(faucet)
        // 模拟购买步骤（这里是测试网络地址转移到自己的钱包，所以直接发起交易）
        await stdlib.transfer(faucet, account, stdlib.parseCurrency(value));
        //交易处理后重新查询账户余额
        const balanceNumber = await getBalanceHandle(account)
        setRecipient({
            ...recipient,
            balanceNumber,
            buySwitch: false,
            inputSwitch: true
        })
        message.info(`你购买了${value}${standardUnit}`, 1)
    }

    //这段代码其实是在reach后端去执行的，所以要传过去
    // Fun([], UInt) 这里格式的意思是定义一个传值为空的函数，然后返回一个UInt数据
    const getHand = async () => {
        const hand = await new Promise(resolve => {
            //关闭合约地址
            setRecipient({
                ...recipient,
                playSwitch: true,
                waitAction: false,

            })
            resolveFuc2.current = resolve
        })
        //
        console.log(`我拿到手势了`, hand)
        return handToInt[hand]
    }
    const random = () => {
        return stdlib.hasRandom.random();
    }

    const playHand = (hand) => {
        resolveFuc2.current && resolveFuc2.current(hand)
    }

    const informTimeout = () => {
        console.log(`超时处理执行`)
    }

    const seeOutcome = (i) => {
        console.log(`胜负的结果是${i}`)
        setRecipient({
            ...recipient,
            lastResult: intToOutcome[i]
        })
    }
    //支付处理
    const acceptWager = async (wagerUInt) => {
        const wager = stdlib.formatCurrency(wagerUInt)
        await new Promise(resolve => {
            //打开支付开关并调用支付
            setRecipient({
                ...recipient,
                payWager: wager,
                paySwitch: true
            })
            resolveFuc1.current = resolve
        })
    }
    //链接合约，并将相关的执行函数传过去给合约执行
    const linkConnectHandle = (str) => {
        const ctAccount = account.attach(RoleType, JSON.parse(str));
        let obj = {
            getHand,
            informTimeout,
            seeOutcome,
            acceptWager,
            random,
            ...stdlib.hasConsoleLogger,

        }
        console.log(obj)
        RoleType.Bob(ctAccount, obj)
    }
    //确定支付，其实就是执行promise的函数，让它不在阻塞线程
    const confirmPay = () => {
        resolveFuc1.current && resolveFuc1.current()
        setRecipient({
            ...recipient,
            paySwitch: false,
            inputSwitch: false,
            waitAction: true
        })
    }


    //获取地址的代币数量
    //who参数是地址对象传入
    const getBalanceHandle = async (who) => {
        //balaceOf查询得到是hash余额，然后formatCurrency转换成数字语言
        return stdlib.formatCurrency(await stdlib.balanceOf(who), 4)
    }

    return <div className={styles.recipientView}>

        {recipient.buySwitch && <div className={styles.generateToken}>
            <Input
                placeholder={'输入购买的数量'}
                value={recipient.number}
                onChange={(e) => {
                    setRecipient({
                        ...recipient,
                        number: e.target.value,
                    })
                }}
                onPressEnter={(e) => {
                    onBuyTokenHandle(e.target.value)
                }}
                suffix={standardUnit} />

            <div className={styles.buttonView}>
                <Button onClick={() => {
                    onBuyTokenHandle(recipient.number)
                }} type={'primary'}>{'确定'}</Button>
                <Button onClick={() => {
                    setRecipient({
                        ...recipient,
                        buySwitch: false,
                        inputSwitch: true

                    })
                }} type={'default'}>{'跳过'}</Button>
            </div>

        </div>}

        {recipient.inputSwitch && <div className={styles.generateToken}>
            <TextArea value={recipient.connectAddress} onChange={(e) => setRecipient({
                ...recipient,
                connectAddress: e.target.value
            })} onPressEnter={(e) => linkConnectHandle(e.target.value)}></TextArea>
        </div>}

        {recipient.paySwitch && <div className={styles.generateToken}>
            <span>{`你将会支付${recipient.payWager} ${standardUnit}参与这个游戏？`} </span>
            <div>
                <Button onClick={() => confirmPay()} type={'primary'} >{'Confirm'}</Button>
                <Button type={'default'} >{'Cannel'}</Button>
            </div>
        </div>}


        {recipient.waitAction && <div className={styles.generateToken}>
            <Spin tip={'等待其他动作确认中...'}></Spin>
        </div>}


        {recipient.playSwitch && <div className={styles.generateToken}>
            {Object.keys(handToInt).map((item, index) => <Button onClick={() => playHand(item)} key={index}>{item}</Button>)}
        </div>}

        {recipient.lastResult && <div className={styles.generateToken}>
            <span>{recipient.lastResult}</span>
        </div>}
    </div>

}


const RecipientView = connect(state => ({ ...state.home }), { ...Actions })(Recipient);



function Airdropper({ account }) {
    const address = account.networkAccount.address
    const resolveFuc = useRef(null)
    const [airdropperData, setAirdropperData] = useState({
        //购买的代币数量
        number: null,
        //显示购买视图
        buyFinsh: false,
        //余额
        balanceNumber: 0,
        //地址
        address: '',
        //空投视图
        giveFinsh: false,
        //空投数量
        giveNumber: 0,
        //合约地址
        contractAddress: '',
        //空投成功提示开关
        successSwitch: false,
        // 复制开关
        copySwitch: false,
        //出手势处理
        playSwitch: false,
        //等待动作处理
        waitAction: false,
        lastResult: null

    })

    useEffect(async () => {
        const balanceNumber = await getBalanceHandle(account)
        setAirdropperData({
            ...airdropperData,
            balanceNumber
        })
    }, [])

    //购买处理（暂时简化增加代币）
    const onBuyTokenHandle = async (value) => {
        if (!value) {
            return
        }
        //获取当前区块链网络
        const faucet = await stdlib.getFaucet()
        // console.log(faucet)
        // 模拟购买步骤（这里是测试网络地址转移到自己的钱包，所以直接发起交易）
        await stdlib.transfer(faucet, account, stdlib.parseCurrency(value));
        //交易处理后重新查询账户余额
        const balanceNumber = await getBalanceHandle(account)
        setAirdropperData({
            ...airdropperData,
            balanceNumber,
            buyFinsh: true,
            giveFinsh: true
        })
        message.info(`你购买了${value}${standardUnit}`, 1)
    }

    //获取地址的代币数量
    //who参数是地址对象传入
    const getBalanceHandle = async (who) => {
        //balaceOf查询得到是hash余额，然后formatCurrency转换成数字语言
        return stdlib.formatCurrency(await stdlib.balanceOf(who), 4)
    }

    //空投处理步骤
    const giveTokenHandle = async (value) => {
        console.log(airdropperData.balanceNumber, value)
        if (parseFloat(airdropperData.balanceNumber) < parseFloat(value)) {
            message.info('参与游戏赌注的代币数量超过当前拥有的数量', 1)
            return
        }

        //depoloy与后端的类进行链接处理
        const ctAccount = account.deploy(RoleType)
        // console.log(ctAccount)
        // //转换成hash交易代币数量
        const amt = stdlib.parseCurrency(value)
        console.log(amt)
        let config = {
            wager: amt,
            getHand,
            informTimeout,
            seeOutcome,
            random,
            ...stdlib.hasConsoleLogger,

        }
        console.log(config)
        RoleType.Alice(ctAccount, config)
        // //获取空投的合约地址
        const newinfo = await ctAccount.getInfo()
        // console.log(newinfo)
        const contractAddress = JSON.stringify(newinfo, null, 2)
        // console.log(contractAddress)
        setAirdropperData({
            ...airdropperData,
            giveNumber: value,
            contractAddress,
            giveFinsh: false,
            successSwitch: true,

        })
        message.info('合约部署成功', 1)

    }
    //复制地址处理到粘贴面板
    const copyContractHandle = async () => {
        navigator.clipboard.writeText(airdropperData.contractAddress);
        setAirdropperData({
            ...airdropperData,
            copySwitch: true,
            waitAction: true
        })
        await waitSleepHandle(5000);

    }
    //这段代码其实是在reach后端去执行的，所以要传过去
    // Fun([], UInt) 这里格式的意思是定义一个传值为空的函数，然后返回一个UInt数据
    const getHand = async () => {
        const hand = await new Promise(resolve => {
            //关闭显示合约地址信息的前端结构
            setAirdropperData({
                ...airdropperData,
                waitAction: false,
                copySwitch: false,
                playSwitch: true
            })
            resolveFuc.current = resolve
        })
        //
        console.log(`我拿到手势了`, hand)
        return handToInt[hand]
    }
    const random = () => {
        return stdlib.hasRandom.random();
    }

    const playHand = (hand) => {
        console.log(resolveFuc)
        resolveFuc.current && resolveFuc.current(hand)
    }

    const informTimeout = () => {
        console.log(`超时处理执行`)

    }

    const seeOutcome = (i) => {
        console.log(`胜负的结果是${i}`)
        setAirdropperData({
            ...airdropperData,
            lastResult: intToOutcome[i]
        })
    }

    return <div className={styles.airdropperView}>

        <span className={styles.promptInfo}>{`${address.slice(0, 4)}***${address.slice(address.length - 4, address.length)} 的账号余额 : ${airdropperData.balanceNumber} ${standardUnit}`}</span>

        {!airdropperData.buyFinsh && <div className={styles.generateToken}>
            <Input
                placeholder={'输入购买的数量'}
                value={airdropperData.number}
                onChange={(e) => {
                    setAirdropperData({
                        ...airdropperData,
                        number: e.target.value,
                    })
                }}
                onPressEnter={(e) => {
                    onBuyTokenHandle(e.target.value)
                }}
                suffix={standardUnit} />

            <div className={styles.buttonView}>
                <Button onClick={() => {
                    onBuyTokenHandle(airdropperData.number)
                }} type={'primary'}>{'确定'}</Button>
                <Button onClick={() => {
                    setAirdropperData({
                        ...airdropperData,
                        buyFinsh: true,
                        giveFinsh: true
                    })
                }} type={'default'}>{'跳过'}</Button>
            </div>

        </div>}


        {airdropperData.giveFinsh && <div className={styles.generateToken}>
            <Input
                placeholder={'请输入赌注大小'}
                value={airdropperData.giveNumber}
                onChange={(e) => {
                    setAirdropperData({
                        ...airdropperData,
                        giveNumber: e.target.value,
                    })
                }}
                onPressEnter={(e) => {
                    giveTokenHandle(e.target.value)
                }}
                suffix={standardUnit} />

            <div className={styles.buttonView}>
                <Button onClick={() => {
                    giveTokenHandle(airdropperData.giveNumber)
                }} type={airdropperData.giveNumber ? 'primary' : 'default'}>{'确定'}</Button>
            </div>
        </div>}

        {airdropperData.successSwitch && <div className={styles.generateToken}>
            <div>
                <span>{airdropperData.contractAddress}</span>
            </div>
            <div className={styles.buttonView}>
                <Button onClick={() => {
                    !airdropperData.copySwitch && copyContractHandle()
                }} type={airdropperData.copySwitch ? 'default' : 'primary'}>{airdropperData.copySwitch ? '已复制' : '复制合约地址'}</Button>
            </div>
        </div>}


        {airdropperData.waitAction && <div className={styles.generateToken}>
            <Spin tip={'等待其他动作确认中...'}></Spin>
        </div>}

        {airdropperData.playSwitch && <div className={styles.generateToken}>
            {Object.keys(handToInt).map((item, index) => <Button onClick={() => playHand(item)} key={index}>{item}</Button>)}
        </div>}

        {airdropperData.lastResult && <div className={styles.generateToken}>
            <span>{airdropperData.lastResult}</span>
        </div>}

    </div>
}

const AirdropperView = connect(state => ({ ...state.home }), { ...Actions })(Airdropper);